package com.shilei;

import com.shilei.common.Dir;
import com.shilei.common.Group;
import com.shilei.common.PropertyMgr;
import com.shilei.common.ResourceMgr;
import com.shilei.strategy.FireStrategy;

import java.awt.*;
import java.util.Random;

/**
 * @description: 坦克类
 * @author: 81271
 * @date: 2020-04-07 21:29
 */
public class Tank extends GameObject {
    public static int HEIGHT = ResourceMgr.goodTankU.getHeight();
    public static int WIDTH = ResourceMgr.goodTankU.getWidth();

    private boolean moveBl = true;
    private boolean liveBl = true;

    private int prevX;
    private int prevY;


    private static final int SPEED = 5;

    private Dir dir;
    private Group group;
    private Random random = new Random();

    private FireStrategy fireStrategy;

    private Rectangle rect = new Rectangle();



    public Tank(int x, int y, Dir dir, Group group) {
        this.x = x;
        this.y = y;
        this.dir = dir;
        this.group = group;



        rect.x = this.x;
        rect.y = this.y;
        rect.width = WIDTH;
        rect.height = HEIGHT;

        try {
            if (Group.Good.equals(this.group))
                fireStrategy = (FireStrategy) Class.forName(String.valueOf(PropertyMgr.get("superFire"))).newInstance();
            else if (Group.Bad.equals(this.group))
                fireStrategy = (FireStrategy) Class.forName(String.valueOf(PropertyMgr.get("defaultFire"))).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }

        GameModel.getInstance().gameObjectList.add(this);

    }

    public void setDir(Dir dir) {
        this.dir = dir;
    }

    public void setMoveBl(boolean moveBl) {
        this.moveBl = moveBl;
    }

    public void paint(Graphics g) {
        if (!liveBl) {
            GameModel.getInstance().gameObjectList.remove(this);
        }

        switch (dir) {
            case LEFT:
                g.drawImage(Group.Good.equals(this.group) ? ResourceMgr.goodTankL: ResourceMgr.badTankL, x, y, null);
                break;
            case RIGHT:
                g.drawImage(Group.Good.equals(this.group) ? ResourceMgr.goodTankR: ResourceMgr.badTankR, x, y, null);
                break;
            case UP:
                g.drawImage(Group.Good.equals(this.group) ? ResourceMgr.goodTankU: ResourceMgr.badTankU, x, y, null);
                break;
            case DOWN:
                g.drawImage(Group.Good.equals(this.group) ? ResourceMgr.goodTankD: ResourceMgr.badTankD, x, y, null);
                break;
        }

        move();
    }

    private void move() {
        prevX = x;
        prevY = y;

        if (!moveBl) {
            return;
        }
        switch (dir) {
            case LEFT:
                x -= SPEED;
                break;
            case RIGHT:
                x += SPEED;
                break;
            case UP:
                y -= SPEED;
                break;
            case DOWN:
                y += SPEED;
                break;
        }


        if (Group.Bad.equals(this.group) && random.nextInt(100) > 95)
            fire();

        if (Group.Bad.equals(this.group) && random.nextInt(100) > 95)
            randomDir();

        boundsCheck();

        rect.x = this.x;
        rect.y = this.y;

    }

    private void boundsCheck() {
        if (this.x < 2) x = 2;
        if (this.y < 32) y = 32;
        if (this.x > TankFrame.GAME_WIDTH - Tank.WIDTH -2) x = TankFrame.GAME_WIDTH - Tank.WIDTH -2;
        if (this.y > TankFrame.GAME_HEIGHT - Tank.HEIGHT -2 ) y = TankFrame.GAME_HEIGHT -Tank.HEIGHT -2;
    }

    private void randomDir() {
        this.dir = Dir.values()[random.nextInt(4)];
    }

    public void fire () {
        fireStrategy.fire(this);
    }

    public void die() {
        liveBl = false;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public Dir getDir() {
        return dir;
    }

    public Group getGroup() {
        return group;
    }

    public Rectangle getRect() {
        return rect;
    }

    public void restoration() {
        x = prevX;
        y = prevY;
    }

    @Override
    public int getHeight() {
        return HEIGHT;
    }

    @Override
    public int getWidth() {
        return WIDTH;
    }
}
